package com.zhj.util.easyexcel;


import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 组装EXCEL表头及总体样式
 *
 */
@SuppressWarnings("unchecked")
public class ExcelStyleHandler {

	/**
	 * 获取表头特定格式
	 * @param headerJson
	 * @return
	 */
	public static List<List<String>> getHeader(String headerJson){
		//解析常用树数据结构 表头键为 label 子集对象叫children
		List<Map<String, Object>> headerMap= (List<Map<String, Object>>) JSON.parse(headerJson);
		List<List<String>> header=new ArrayList<>();
		if(headerMap.get(0).containsKey("children")) {
			header=recursionHeadTree(headerMap, header, 0);
		}else {
			for(Map<String, Object> temp:headerMap) {
				List<String> result=new ArrayList<>();
				result.add(temp.get("label").toString());
				header.add(result);
			}
		}
		return header;
	}
	/**
	 * 递归表头树
	 * @return
	 */
	public static List<List<String>> recursionHeadTree(List<Map<String, Object>> dataInfo,List<List<String>> result,int i){
		for(Map<String, Object> temp:dataInfo) {
			if("[]".equals(temp.get("children").toString())|| StringUtils.isEmpty(temp.get("children").toString())) {
				List<Map<String, Object>> children=(List<Map<String, Object>>) JSON.parse(temp.get("children").toString());
				if(temp.containsKey("lastname")) {
					List<String> prefix=Arrays.asList(temp.get("lastname").toString().split("\\|\\|"));
					List<String> prefix2 = new ArrayList<>(prefix);
					prefix2.add(temp.get("label").toString());
					result.add(prefix2);
				}else {
					children.add(temp);
					result.add(children.stream().map(x->x.get("label").toString()).collect(Collectors.toList()));
				}
			}
			else {
				List<Map<String, Object>> children=(List<Map<String, Object>>) JSON.parse(temp.get("children").toString());
				for(Map<String, Object> temp2:children) {
					temp2.put("lastname", temp.containsKey("lastname")?temp.get("lastname").toString()+"||"+temp.get("label").toString():temp.get("label").toString());
				}
				recursionHeadTree(children,result,i);
			}
		}
		return result;
	}
	/**
	 * 组装表头数据 解析列宽数据，绑定字段数据
	 * @param dynamicHeadVoJson
	 * @return
	 */
	public static Map<String, Object> getHeadAndWidthAndProp(String dynamicHeadVoJson){
		//获取组装表头对象
		List<DynamicHeadVO> dataInfo=JSONArray.parseArray(dynamicHeadVoJson, DynamicHeadVO.class);
		//表头名称获取
		List<List<String>> result_head=new ArrayList<>();
		//列宽数据获取
		List<Map<Integer,Integer>> result_width=new ArrayList<>();
		//绑定字段获取
		List<String> result_prop=new ArrayList<>();
		//获取数据集
		Map<String, Object> result=recursionHeadTreeV2(dataInfo, result_width,result_prop, result_head, 0);
		return result;
	}
	/**
	 * 递归表头树
	 * @param dataInfo 表头||列宽||绑定字段数据集
	 * @param result   最终返回值
	 * @param i
	 * @return
	 */
	public static Map<String, Object> recursionHeadTreeV2(List<DynamicHeadVO> dataInfo,List<Map<Integer,Integer>> result_width,List<String> result_prop,List<List<String>> result_head,int i){
		for(DynamicHeadVO temp:dataInfo) {
			if(StringUtils.isEmpty(temp.getChildren())||temp.getChildren().size()==0) {
				//判断此字段前缀是否为空
				if(!StringUtils.isEmpty(temp.getLastname())) {
					List<String> prefix=Arrays.asList(temp.getLastname().split("\\|\\|"));
					prefix= new ArrayList<>(prefix);
					prefix.add(temp.getLabel());
					result_head.add(prefix);
				}else {
					temp.getChildren().add(temp);
					result_head.add(temp.getChildren().stream().map(x->x.getLabel()).collect(Collectors.toList()));
				}
				//临时写法
				if(!StringUtils.isEmpty(temp.getWidth())) {
					result_width.add((Map<Integer,Integer>)JSONObject.parseObject(temp.getWidth(), Map.class));
				}
				result_prop.add(temp.getProp());
			}
			else {
				for(DynamicHeadVO temp2:temp.getChildren()) {
					temp2.setLastname(!StringUtils.isEmpty(temp.getLastname())?temp.getLastname()+"||"+temp.getLabel():temp.getLabel());
				}
				recursionHeadTreeV2(temp.getChildren(),result_width,result_prop,result_head,i);
			}
		}
		//组装返回数据集
		Map<String, Object> result=new HashMap<>();
		result.put("result_head", result_head);
		result.put("result_prop", result_prop);
		result.put("result_width", result_width);
		return result;
	}
	/**
	 * 获取列宽
	 * @param columnJson
	 * @return
	 */
	public static Map<Integer,Integer> getColumnWidth(String columnJson){
		Map<Integer,Integer> columnWidthMap=(Map<Integer, Integer>)JSON.parse(columnJson);
		return columnWidthMap;
	}
	/**
	 * 获取列宽
	 * @param columnJson
	 * @return
	 */
	public static Map<Integer,Integer> getColumnWidthV2(List<Map<Integer,Integer>> widths){
		if(StringUtils.isEmpty(widths)||widths.size()==0) {
			return null;
		}
		Map<Integer,Integer> columnWidthMap = widths.stream()
				.map(Map::entrySet)
				.flatMap(Set::stream)
				.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
		return columnWidthMap;
	}
	/**
	 * 设置表头格式
	 * 简易 后有时间再改为可更改表头设置
	 */
	public static WriteCellStyle setHeadStyle() {
		// 头的策略
		WriteCellStyle headWriteCellStyle = new WriteCellStyle();
		// 背景设置为白色
//      headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		WriteFont headWriteFont = new WriteFont();
		headWriteFont.setFontHeightInPoints((short)12);
		headWriteFont.setFontName("等线");
		headWriteCellStyle.setWriteFont(headWriteFont);
		return headWriteCellStyle;
	}
	/**
	 * 设置内容格式
	 * 简易 后有时间再改为可更改内容设置
	 */
	public static WriteCellStyle setContentStyle() {
		// 内容的策略
		WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
		// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
		contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
		// 背景白色
		contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		WriteFont contentWriteFont = new WriteFont();
		// 字体大小
		contentWriteFont.setFontHeightInPoints((short)11);
		contentWriteFont.setFontName("等线");
		contentWriteCellStyle.setWriteFont(contentWriteFont);
		contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
		contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
		contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
		contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
		return contentWriteCellStyle;
	}
	/**
	 * 处理数据为excel接收格式
	 * @param dataList
	 * @return
	 */
	public static List<List<Object>> getDataInfo(List<LinkedHashMap<String, Object>> dataList){
		//处理过的值  键值只余值
		List<List<Object>> dataInfo=dataList.stream().map(x->new ArrayList<Object>(x.values())).collect(Collectors.toList());
		return dataInfo;
	}
	/**
	 * 处理数据为excel接收格式
	 * @param dataList
	 * @return
	 */
	public static List<List<Object>> getDataInfoV2(List<LinkedHashMap<String, Object>> dataList,List<String> props){
		//临时写法
		List<List<Object>> dataInfo=new ArrayList<>();
		List<LinkedHashMap<String, Object>> dataList2=new ArrayList<>();
		for(LinkedHashMap<String, Object> temp:dataList) {
			LinkedHashMap<String, Object> result=new LinkedHashMap<String, Object>();
			for(String temp2:props) {
				result.put(temp2, temp.get(temp2));
			}
			dataList2.add(result);
		}
		//处理过的值  键值只余值
		dataInfo=dataList2.stream().map(x->new ArrayList<Object>(x.values())).collect(Collectors.toList());
		return dataInfo;
	}
}
